package cn.kpt.auth.controller;

import cn.kpt.auth.service.MailService;
import cn.kpt.auth.service.UserService;
import cn.kpt.beans.dto.Dto;
import cn.kpt.beans.pojo.ItripUser;
import cn.kpt.beans.vo.userinfo.ItripUserVO;
import cn.kpt.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

//- @Api()用于类；
//表示标识这个类是swagger的资源
@Api(tags = "注册控制器")
//① 是否可以返回页面
//　　答：@RestController无法返回指定页面，而@Controller可以。
//　　解析：对于Controller， 如果只是使用@RestController注解，则其方法无法返回指定页面，此时配置的视图解析器 InternalResourceViewResolver不起作用，返回的内容就是 return 里的内容。 如果需要返回到指定页面，则需要用 @Controller配合视图解析器InternalResourceViewResolver才行。
//② 返回内容
//　　如果需要返回JSON，XML或自定义mediaType内容到页面，@RestController自己就可以搞定,这个注解对于返回数据比较方便，因为它会自动将对象实体转换为JSON格式。而@Controller需要在对应的方法加上@ResponseBody注解。
@RestController
//映射请求，也就是通过它来指定控制器可以处理哪些URL请求
@RequestMapping("/api")
public class RegisterController {

    @Resource
    private UserService userService;
    @Resource
    private MailService mailService;

    @ApiOperation(value = "用户手机号注册",
            notes = "用户填写手机号进行注册，会收到注册激活码。<br/>" +
                    "成功：success='true' | 失败：success='false' 且返回错误代码，错误码如下：<br/>" +
                    "<ul>" +
                    "<li>300003：注册参数错误</li>" +
                    "<li>300001：用户已经注册</li>" +
                    "<li>300000：注册失败</li>" +
                    "</ul>",
            produces = "application/json;charset=UTF-8")
    @RequestMapping(value = "/registerbyphone", method = RequestMethod.POST)
//1) 该注解用于读取Request请求的body部分数据，使用系统默认配置的HttpMessageConverter进行解析，然后把相应的数据绑定到要返回的对象上；
//2) 再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上。
    public Dto registerbyphone(@RequestBody ItripUserVO vo) {

        try {
//           首先进行表单验证手机号格式验证和密码为空
            if (!ValidateUtil.validPhone(vo.getUserCode()) || EmptyUtils.isEmpty(vo.getUserPassword())) {
                return DtoUtil.returnFail("格式错误", ErrorCode.AUTH_PARAMETER_ERROR);
            }
//          验证手机号是否已经注册
            ItripUser itripUser = userService.checkUserIsExists(vo.getUserCode());
            if (EmptyUtils.isNotEmpty(itripUser.getUserCode())) {
//                0，，没有激活  1激活
                if (itripUser.getActivated() == 1) {
                    return DtoUtil.returnFail("已经注册，直接登录", ErrorCode.AUTH_USER_ALREADY_EXISTS);
                }
            }
//           手机号是空的  没有注册的 设置相关信息
            itripUser.setUserCode(vo.getUserCode());
            itripUser.setUserPassword(MD5.getMd5(vo.getUserPassword(), 16));
            itripUser.setUserName(vo.getUserName());
//            发送验证码
            userService.saveInfo(itripUser);
            return DtoUtil.returnSuccess();
        } catch (Exception e) {
            e.printStackTrace();
            return DtoUtil.returnFail("注册失败", ErrorCode.AUTH_UNKNOWN);
        }
    }

    @ApiOperation(value = "手机号注册用户激活",
            notes = "手机号注册的用户可以根据手机号和激活码进行用户激活。<br/>" +
                    "成功：success='true' | 失败：success='false' 和 错误代码，错误码如下：<br/>" +
                    "<ul>" +
                    "<li>300003：手机号格式错误</li>" +
                    "<li>300001：用户已经激活</li>" +
                    "<li>300007：用户还未注册</li>" +
                    "<li>300004：激活码已经过期</li>" +
                    "<li>300000：激活失败</li>" +
                    "</ul>",
            produces = "application/json;charset=UTF-8"
    )
    @ApiImplicitParams({
            @ApiImplicitParam(name = "user", value = "手机号", required = true, paramType = "query"),
            @ApiImplicitParam(name = "code", value = "激活码", required = true, paramType = "query")
    })
    @RequestMapping(value = "/validatephone", method = RequestMethod.PUT)
//     根据前段请求需要返回user 和code
//    @RequestParam （org.springframework.web.bind.annotation.RequestParam）用于将指定的请求参数赋值给方法中的形参。
//   （1）value：请求参数名（必须配置）
//   （2）required：是否必需，默认为 true，即 请求中必须包含该参数，如果没有包含，将会抛出异常（可选配置）
//   （3）defaultValue：默认值，如果设置了该值，required 将自动设为 false，无论你是否配置了required，配置了什么值，都是 false（可选配置）
    public Dto validatephone(@RequestParam String user, @RequestParam String code) {
        try {
//            前端都表单所以先表单验证(手机号验证部分)
            if (!ValidateUtil.validPhone(user)) {
                return DtoUtil.returnFail("手机号格式错误！", ErrorCode.AUTH_PARAMETER_ERROR);
            }
//            通过则验证手机号是否注册
            ItripUser itripUser = userService.checkUserIsExists(user);
            if (EmptyUtils.isNotEmpty(itripUser.getUserCode())) {
//                注册过检查是否激活过
                if (itripUser.getActivated() == 1) {
                    return DtoUtil.returnFail("该用户已经激活过！请勿重复激活！", ErrorCode.AUTH_USER_ALREADY_EXISTS);
                }
            } else {
                return DtoUtil.returnFail("该用户还未注册！请先去注册！", ErrorCode.AUTH_ILLEGAL_USERCODE);
            }
//             前端都表单所以先表单验证(验证码验证部分)
//            从Redis中获取验证码
            if (!userService.checkActiveCode(user, code)) {
                return DtoUtil.returnFail("激活码错误或已经过期！", ErrorCode.AUTH_ACTIVATE_FAILED);
            }
//           用户进行激活
            userService.activeUser(itripUser);
//            返回激活成功
            return DtoUtil.returnSuccess();
        } catch (Exception e) {
            e.printStackTrace();
            return DtoUtil.returnFail("激活失败！", ErrorCode.AUTH_UNKNOWN);
        }
    }

    /**
     * 邮箱验证
     *
     * @param name
     * @return
     */
    @RequestMapping(value = "/ckusr", method = RequestMethod.GET)
    public Dto ckusr(@RequestParam String name) {
        try {
            ItripUser user = userService.findByUserCode(name);
//            邮箱验证
            if (user == null) {
                return DtoUtil.returnSuccess();
            } else {
                if (user.getActivated() == 0) {
                    return DtoUtil.returnSuccess("用户已存在！或未激活");
                }
                return DtoUtil.returnFail("用户已存在！", ErrorCode.AUTH_USER_ALREADY_EXISTS);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return DtoUtil.returnFail("注册失败", ErrorCode.AUTH_UNKNOWN);
        }
    }

    /**
     * 邮箱注册
     *
     * @param userVO
     * @return
     */
    @RequestMapping(value = "/doregister", method = RequestMethod.POST)
    public Dto doRegister(@RequestBody ItripUserVO userVO) {
//        表单验证
        if (!ValidateUtil.validEmail(userVO.getUserCode())) {
            return DtoUtil.returnFail("请使用正确的邮箱地址注册", ErrorCode.AUTH_ILLEGAL_USERCODE);
        }
        try {
//            创建用户
            ItripUser user = new ItripUser();
            user.setUserCode(userVO.getUserCode());
            user.setUserPassword(userVO.getUserPassword());
            user.setUserType(0);
            user.setActivated(0);
            user.setUserName(userVO.getUserName());
//            判断邮箱是否存在
            if (EmptyUtils.isEmpty(userService.findByUserCode(user.getUserCode()))) {
                user.setUserPassword(MD5.getMd5(user.getUserPassword(), 16));
//                发送验证码
                userService.itriptxCreateUser(user);
                return DtoUtil.returnSuccess();
            } else {
                if(userService.findByUserCode(userVO.getUserCode()).getActivated() == 0){
                    user.setUserPassword(MD5.getMd5(user.getUserPassword(), 16));
//                发送验证码
                    userService.itriptxCreateUsers(user);
                    return DtoUtil.returnSuccess();
                }
                return DtoUtil.returnFail("用户已存在，请激活", ErrorCode.AUTH_USER_ALREADY_EXISTS);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return DtoUtil.returnFail(e.getMessage(), ErrorCode.AUTH_UNKNOWN);
        }
    }

    /**
     * 邮箱激活
     *
     * @param user
     * @param code
     * @return
     */
    @RequestMapping(value = "/activate", method = RequestMethod.PUT)
    public Dto activate(@RequestParam String user, @RequestParam String code) {
        try {
            if (userService.activate(user, code)) {
                return DtoUtil.returnSuccess("激活成功");
            } else {
                return DtoUtil.returnFail("激活失败", ErrorCode.AUTH_ACTIVATE_FAILED);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return DtoUtil.returnFail("激活失败", ErrorCode.AUTH_UNKNOWN);
        }
    }
}
